import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from "react";
import { Text, View } from "react-native";
import * as Animatable from "react-native-animatable";
import { Ionicons } from "@expo/vector-icons";
import { alertConfigStyle, styles } from "./index.styles";
import { AlertPropsType, AlertRefType, AlertType } from "./types";

/**
 @author:  BelovedLYC
 @description: AlertComponent
 @param {'success' | 'error' | 'primary'} code - 提示类型标识
 @param {string} message - 提示信息
 @param {number} duration - 提示持续时间
 @param {function} onHide - 提示隐藏回调函数
 @param {string} animationIn - 进入动画名称
 @param {string} animationOut - 退出动画名称
 @param {number} animationInDuration - 进入动画持续时间
 @param {number} animationOutDuration - 退出动画持续时间
 @param {object} style - 自定义样式
 @param {object} ref - 获取dom
 @returns {JSX.Element} - AlertComponent 组件
 @example
 const ref = useRef(null);
 ref.current.show()
 <AlertComponent
 style={{
 position: "absolute",
 top: 0,
 left: 0,
 right: 0,
 zIndex: 9999,
 margin: 20,
 }}
 code="success"
 ref={AlertRef}
 message="操作成功！"
 duration={2000}
 onHide={() => {
 console.log("Alert uninstall");
 }}
 />
 */
const AlertComponent = forwardRef<AlertRefType, AlertPropsType>(
  (
    {
      style,
      duration = 3000,
      onHide,
      animationIn = "fadeIn",
      animationOut = "fadeOut",
      animationInDuration = 500,
      animationOutDuration = 300,
    },
    ref
  ) => {
    const [visible, setVisible] = useState(false);
    const [code, setCode] = useState<AlertType>("success");
    const [message, setMessage] = useState<string>("");
    const animRef = useRef<Animatable.View & View>(null);
    const timeoutRef = useRef<NodeJS.Timeout>();

    useImperativeHandle(ref, () => ({
      show: (code, message) => {
        setCode(code);
        setMessage(message);
        setVisible(true);
        animRef.current?.stopAnimation();
        animRef.current?.[animationIn]?.(animationInDuration);
        resetAutoHide();
      },
      hide: () => {
        animRef.current?.[animationOut]?.(animationOutDuration).then(() => {
          setVisible(false);
          onHide?.();
        });
      },
    }));

    const resetAutoHide = () => {
      if (timeoutRef.current) clearTimeout(timeoutRef.current);
      if (duration > 0) {
        timeoutRef.current = setTimeout(() => {
          animRef.current?.[animationOut]?.(animationOutDuration).then(() => {
            setVisible(false);
            onHide?.();
          });
        }, duration);
      }
    };

    useEffect(() => {
      return () => {
        if (timeoutRef.current) clearTimeout(timeoutRef.current);
      };
    }, []);

    const config = alertConfigStyle[code] || alertConfigStyle.primary;

    if (!visible) return null;

    return (
      <Animatable.View
        ref={animRef}
        useNativeDriver
        style={[styles.container, { backgroundColor: config.bgColor }, style]}
      >
        <Ionicons
          name={config.iconName}
          size={20}
          color={config.iconColor}
          style={styles.icon}
        />
        <Text style={[styles.message, { color: config.textColor }]}>
          {message}
        </Text>
      </Animatable.View>
    );
  }
);

export default AlertComponent;
